package com.jacky.singleton;


interface Singleton{}

class SingleEHan{
    private SingleEHan(){};
    private static SingleEHan instance = new SingleEHan();
    public static SingleEHan getInstance(){
        return instance;
    }
}

class SingleLan{
    private SingleLan(){};
    private static SingleLan instance;
    public static SingleLan getInstance(){
        if (instance == null){
            instance = new SingleLan();
        }
        return instance;
    }
}

class SingleBySynchronized {
    private SingleBySynchronized(){};
    private static SingleBySynchronized instance;
    public static SingleBySynchronized getInstance(){
        synchronized (SingleBySynchronized.class){
            if (instance == null){
                instance = new SingleBySynchronized();
            }
            return instance;
        }
    }
}

class SingleByDCL{
    private SingleByDCL(){};
    private static SingleByDCL instance;
    public static SingleByDCL getInstance(){
        if (instance == null){
            synchronized (SingleByDCL.class){
                if (instance == null){
                    instance = new SingleByDCL();
                }
            }
        }
        return instance;
    }
}

class SingleByVolatile{
    private SingleByVolatile(){};
    private static volatile SingleByVolatile instence;
    public static SingleByVolatile getInstance(){
        if (instence == null){
            synchronized (SingleByVolatile.class){
                if (instence == null){
                    instence = new SingleByVolatile();
                }
            }
        }
        return instence;
    }
}

class SingletonByCons{
    private static class SingletonByConstruct{
        public static SingletonByCons instance = new SingletonByCons();
    }
    public static SingletonByCons getInstance(){
        return SingletonByConstruct.instance;
    }
}

public class Single {
    public static void main(String[] args) {
//        singleEHan();
//        singleLan();
//        singleBySynchronized();
        singleByDCL();
//        singleByVolatile();
//        singletonByCons();
    }

    private static void singletonByCons() {
        System.out.println("singletonByCons");
        for (int i = 0; i < 10; i++) {
            new Thread(){
                @Override
                public void run() {
                    System.out.println(SingletonByCons.getInstance());
                }
            }.start();
        }
    }

    private static void singleByVolatile() {
        System.out.println("singleByVolatile");
        for (int i = 0; i < 10; i++) {
            new Thread(){
                @Override
                public void run() {
                    System.out.println(SingleByVolatile.getInstance());
                }
            }.start();
        }
    }

    private static void singleByDCL() {
        System.out.println("singleByDCL");
        for (int i = 0; i < 10; i++) {
            new Thread(){
                @Override
                public void run() {
                    System.out.println(SingleByDCL.getInstance());
                }
            }.start();
        }
    }

    private static void singleBySynchronized() {
        System.out.println("singleBySynchronized");
        for (int i = 0; i < 10; i++) {
            new Thread(){
                @Override
                public void run() {
                    System.out.println(SingleBySynchronized.getInstance());
                }
            }.start();
        }
    }

    private static void singleLan() {
        System.out.println("singleLan");
        for (int i = 0; i < 10; i++) {
            new Thread(){
                @Override
                public void run() {
                    System.out.println(SingleLan.getInstance());
                }
            }.start();
        }
    }

    private static void singleEHan() {
        System.out.println("singleEHan");
        for (int i = 0; i < 10; i++) {
            new Thread(){
                @Override
                public void run() {
                    System.out.println(SingleEHan.getInstance());
                }
            }.start();
        }
    }

}
